using HCore.Core;
using HCore.Unity.Core;
using UnityEngine;

namespace HCore.Tests.Runtime.MyMesh
{
    public class TestMyMesh : MonoBehaviour
    {
        private void Start()
        {
            CreateAnimationMesh();
        }

        /// <summary>
        ///     创建三角形栅格
        /// </summary>
        public void CreateTriangleMesh()
        {
            var mesh = new Mesh();


            GameUtils.CreateEmptyMeshArrays(
                3, out var vertices,
                3, out var uv,
                3, out var triangles);

            vertices[0] = new Vector3(0, 0);
            vertices[1] = new Vector3(0, 100);
            vertices[2] = new Vector3(100, 100);

            // uv纹理是按照0~1来进行定位的 从纹理点上映射到 vertices 对应的点上
            uv[0] = new Vector2(0, 0);
            uv[1] = new Vector2(0, 1);
            uv[2] = new Vector2(1, 1);

            // 索引应总是按照顺时针进行设置
            triangles[0] = 0;
            triangles[1] = 1;
            triangles[2] = 2;

            mesh.vertices = vertices;
            mesh.uv = uv;
            mesh.triangles = triangles;

            GetComponent<MeshFilter>().mesh = mesh;
        }

        /// <summary>
        ///     创建四边形栅格
        /// </summary>
        public void CreateQuadMesh()
        {
            var mesh = new Mesh();

            GameUtils.CreateEmptyQuadMeshArrays(
                1,
                out var vertices,
                out var uv,
                out var triangles);

            vertices[0] = new Vector3(0, 0);
            vertices[1] = new Vector3(0, 100);
            vertices[2] = new Vector3(100, 100);
            vertices[3] = new Vector3(100, 0);

            // uv纹理是按照0~1来进行定位的 从纹理点上映射到 vertices 对应的点上
            uv[0] = new Vector2(0, 0);
            uv[1] = new Vector2(0, 1);
            uv[2] = new Vector2(1, 1);
            uv[3] = new Vector2(1, 0);

            // 索引应总是按照顺时针进行设置
            triangles[0] = 0;
            triangles[1] = 1;
            triangles[2] = 2;

            triangles[3] = 0;
            triangles[4] = 2;
            triangles[5] = 3;

            mesh.vertices = vertices;
            mesh.uv = uv;
            mesh.triangles = triangles;

            GetComponent<MeshFilter>().mesh = mesh;
        }

        /// <summary>
        ///     创建瓦片栅格
        /// </summary>
        public void CreateTileMesh()
        {
            var mesh = new Mesh();
            const int width = 4;
            const int height = 4;
            const float tileSize = 10f;

            GameUtils.CreateEmptyQuadMeshArrays(
                width * height,
                out var vertices,
                out var uv,
                out var triangles);

            ForUtils.For(width, height, (i, j) =>
            {
                var index = i * height + j;

                vertices[index * 4 + 0] = new Vector3(tileSize * i, tileSize * j);
                vertices[index * 4 + 1] = new Vector3(tileSize * i, tileSize * (j + 1));
                vertices[index * 4 + 2] = new Vector3(tileSize * (i + 1), tileSize * (j + 1));
                vertices[index * 4 + 3] = new Vector3(tileSize * (i + 1), tileSize * j);

                // uv纹理是按照0~1来进行定位的 从纹理点上映射到 vertices 对应的点上
                uv[index * 4 + 0] = new Vector2(0, 0);
                uv[index * 4 + 1] = new Vector2(0, 1);
                uv[index * 4 + 2] = new Vector2(1, 1);
                uv[index * 4 + 3] = new Vector2(1, 0);

                // 索引应总是按照顺时针进行设置
                triangles[index * 6 + 0] = index * 4 + 0;
                triangles[index * 6 + 1] = index * 4 + 1;
                triangles[index * 6 + 2] = index * 4 + 2;

                triangles[index * 6 + 3] = index * 4 + 0;
                triangles[index * 6 + 4] = index * 4 + 2;
                triangles[index * 6 + 5] = index * 4 + 3;
            });


            mesh.vertices = vertices;
            mesh.uv = uv;
            mesh.triangles = triangles;

            GetComponent<MeshFilter>().mesh = mesh;
        }


        /// <summary>
        ///     创建动画栅格
        /// </summary>
        public void CreateAnimationMesh()
        {
            var mesh = new Mesh();


            GameUtils.CreateEmptyQuadMeshArrays(
                2,
                out var vertices,
                out var uv,
                out var triangles);


            ///// SpartanSpriteSheet.png 长宽
            const float textureWidth = 512f;
            const float textureHeight = 512f;


            #region Body

            const float bodySize = 70f;
            var bodyPosition = new Vector3(0, -50);

            vertices[0] = bodyPosition + new Vector3(0, 0);
            vertices[1] = bodyPosition + new Vector3(0, bodySize);
            vertices[2] = bodyPosition + new Vector3(bodySize, bodySize);
            vertices[3] = bodyPosition + new Vector3(bodySize, 0);


            ///// 这里创建的是 SpartanSpriteSheet.png 素材中的 头像左下角和右上角像素点坐标
            var bodyPixelsLowerLeft = new Vector2(0, 256);
            var bodyPixelsUpperRight = new Vector2(128, 384);

            // uv纹理是按照0~1来进行定位的 从纹理点上映射到 vertices 对应的点上
            uv[0] = new Vector2(bodyPixelsLowerLeft.x / textureWidth, bodyPixelsLowerLeft.y / textureHeight);
            uv[1] = new Vector2(bodyPixelsLowerLeft.x / textureWidth, bodyPixelsUpperRight.y / textureHeight);
            uv[2] = new Vector2(bodyPixelsUpperRight.x / textureWidth, bodyPixelsUpperRight.y / textureHeight);
            uv[3] = new Vector2(bodyPixelsUpperRight.x / textureWidth, bodyPixelsLowerLeft.y / textureHeight);

            // 索引应总是按照顺时针进行设置
            triangles[0] = 0;
            triangles[1] = 1;
            triangles[2] = 2;

            triangles[3] = 0;
            triangles[4] = 2;
            triangles[5] = 3;

            #endregion

            #region Head

            const float headSize = 55f;
            var headPosition = new Vector3(6, -12);

            vertices[4] = headPosition + new Vector3(0, 0);
            vertices[5] = headPosition + new Vector3(0, headSize);
            vertices[6] = headPosition + new Vector3(headSize, headSize);
            vertices[7] = headPosition + new Vector3(headSize, 0);


            ///// 这里创建的是 SpartanSpriteSheet.png 素材中的 头像左下角和右上角像素点坐标
            var headPixelsLowerLeft = new Vector2(0, 384);
            var headPixelsUpperRight = new Vector2(128, 512);

            // uv纹理是按照0~1来进行定位的 从纹理点上映射到 vertices 对应的点上
            uv[4] = new Vector2(headPixelsLowerLeft.x / textureWidth, headPixelsLowerLeft.y / textureHeight);
            uv[5] = new Vector2(headPixelsLowerLeft.x / textureWidth, headPixelsUpperRight.y / textureHeight);
            uv[6] = new Vector2(headPixelsUpperRight.x / textureWidth, headPixelsUpperRight.y / textureHeight);
            uv[7] = new Vector2(headPixelsUpperRight.x / textureWidth, headPixelsLowerLeft.y / textureHeight);

            // 索引应总是按照顺时针进行设置
            triangles[6] = 4;
            triangles[7] = 5;
            triangles[8] = 6;

            triangles[9] = 4;
            triangles[10] = 6;
            triangles[11] = 7;

            #endregion


            mesh.vertices = vertices;
            mesh.uv = uv;
            mesh.triangles = triangles;

            #region Animation

            var headPositionY = -12f;
            var headPositionMoveDown = true;
            FunctionBehaviour.AddUpdate(() =>
            {
                if (headPositionMoveDown)
                {
                    headPositionY += -5f * Time.deltaTime;
                    if (headPositionY < -13f) headPositionMoveDown = false;
                }
                else
                {
                    headPositionY += 5f * Time.deltaTime;
                    if (headPositionY > -10f) headPositionMoveDown = true;
                }

                headPosition = new Vector3(6, headPositionY);

                vertices[4] = headPosition + new Vector3(0, 0);
                vertices[5] = headPosition + new Vector3(0, headSize);
                vertices[6] = headPosition + new Vector3(headSize, headSize);
                vertices[7] = headPosition + new Vector3(headSize, 0);

                mesh.vertices = vertices;
            });

            #endregion

            GetComponent<MeshFilter>().mesh = mesh;
        }
    }
}